package com.winit.projectPlan.manager;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.base.web.BaseController;
import com.winit.commons.util.HttpClientUtil;
import com.winit.projectPlan.model.ProjectPlan;
import com.winit.projectPlan.model.Task;
import com.winit.projectPlan.model.TaskStatus;
import com.winit.projectPlan.repository.TaskRepository;
import com.winit.projectPlan.repository.TaskRepositoryExt;
import com.winit.projectPlan.service.IProjectPlanService;
import com.winit.projectPlan.web.MemberTaskInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigInteger;
import java.util.*;

@Component
public class TaskManager {

    private static Logger log = LoggerFactory.getLogger(TaskManager.class);

    @Value("${url_beetle_plan}")
    private String BEETLE_PLAN_SERVER;
    @Value("${path_get_plan_user}")
    private String PATH_GET_PLAN_USER;

    @Autowired
    private TaskRepository taskRepository;
    @Autowired
    private TaskRepositoryExt taskRepositoryExt;
    @Autowired
    private IProjectPlanService projectPlanService;

    public Task createTask(Task task){
        task.setId(Task.generateId());
        if (StringUtils.isEmpty(task.getStatus())){
            task.setStatus(TaskStatus.NEW);
        }
        if (StringUtils.isEmpty(task.getNumber())){
            task.setNumber(Task.generateTaskNumber());
        }
        this.taskRepository.save(task);
        return task;
    }

    public Task updateTask(Task task){
        this.taskRepositoryExt.updatePropertiesNotNull(task);
        return this.taskRepository.findOne(task.getId());
    }

    public List<Task> saveTasks(List<Task> tasks){
        List<Task> rs = new ArrayList<>();
        for (Task task : tasks){
            if (StringUtils.isEmpty(task.getId())){
                rs.add(this.createTask(task));
            } else {
                rs.add(this.updateTask(task));
            }
        }
        return rs;
    }

    public List<Task> getTasks(String taskId, String number, String type, String chargerAccount, String status, String projectPlanId){
        return this.taskRepository.getTasks(taskId, number, type, chargerAccount, status, projectPlanId);
    }

    public void deleteTask(String taskId, String number){
        if (StringUtils.isEmpty(taskId) && StringUtils.isEmpty(number)){
            log.error("deleteTask 参数taskId, number均为空，无法执行");
            return;
        }
        this.taskRepository.deleteByIdAndNumber(taskId, number);
    }


    public Collection getMemberTaskStats(String projectPlanId, String tokenId){
        Map<String, MemberTaskInfo> rs = new HashMap<>();
        ProjectPlan projectPlan = this.projectPlanService.getUndeletedProjectPlanById(projectPlanId);
        if (null == projectPlan){
            log.error("对应的project plan未找到，projectPlanId:" + projectPlanId);
            return null;
        }
        String uplanId = projectPlan.getUplanId();
        if(!StringUtils.isEmpty(uplanId)) {
            String url = BEETLE_PLAN_SERVER + PATH_GET_PLAN_USER;
            StringBuilder stringBuilder = new StringBuilder(url);
            stringBuilder.append("?token_id=").append(tokenId);
            stringBuilder.append("&plan_id=").append(uplanId);
            try {
                JSONObject jsonObject = HttpClientUtil.doGetForJson(stringBuilder.toString());
                log.info("get_plan_user from beetle plan, projectPlanId:" + projectPlan.getProjectPlanId() + ",http response:" + jsonObject);
                if (jsonObject.get("success") == null || (!"true".equalsIgnoreCase(jsonObject.get("success").toString()))) {
                    log.error("获取beetle plan user错误:" + jsonObject.get("msg"));
                    return null;
                }
                List<Map<String, String>> data = (List<Map<String, String>>)jsonObject.get("data");
                if (!CollectionUtils.isEmpty(data)){
                    for (Map<String, String> map : data) {
                        MemberTaskInfo memberTaskInfo = new MemberTaskInfo();
                        memberTaskInfo.setAccount(map.get("account"));
                        memberTaskInfo.setRole(map.get("role"));
                        memberTaskInfo.setName(map.get("realname"));
                        rs.put(memberTaskInfo.getAccount(), memberTaskInfo);
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return null;
            }
        }



        List<Map<String, Object>> tempRs =  this.taskRepositoryExt.getMemberTaskStats(projectPlanId);
        if (!CollectionUtils.isEmpty(tempRs)){
            for(Map<String, Object> stats : tempRs){
                String account = (String)stats.get("chargerAccount");
                MemberTaskInfo memberTaskInfo = rs.get(account);
                if (null == memberTaskInfo){
                    memberTaskInfo = new MemberTaskInfo();
                    memberTaskInfo.setAccount(account);
                    memberTaskInfo.setName((String)stats.get("chargerRealname"));
                    rs.put(account, memberTaskInfo);
                }
                String status = (String)stats.get("status");
                BigInteger taskNumTemp = (BigInteger) stats.get("taskNum");
                int taskNum = taskNumTemp == null ? 0 : taskNumTemp.intValue();
                switch (status){
                    case TaskStatus.NEW:  memberTaskInfo.addNewTask(taskNum); break;
                    case TaskStatus.DOING:  memberTaskInfo.addDoingTask(taskNum); break;
                    case TaskStatus.DONE:  memberTaskInfo.addDownTask(taskNum); break;
                    case TaskStatus.CANCEL:  memberTaskInfo.addDownTask(taskNum); break;
                    case TaskStatus.DELAYED:  memberTaskInfo.addDelayedTask(taskNum); break;
                    default:log.error("非法的task status:" + status);
                }
                memberTaskInfo.addTotalTask(taskNum);
            }
        }


        return rs.values();
    }
}
